package mgodb

import (
	"fmt"
	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
	"jgt-oper/src/util"
	"time"
)

// ContactsBook 通讯录
type ContactsBook struct {
	DB *mongo.DB
}

// cContactsBook 通讯录数据表
const cContactsBook = "oper_contacts_book"

// Init 初始化方法
func (a *ContactsBook) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		c.EnsureIndex(mgo.Index{
			Key:    []string{"record_id", "deleted"},
			Unique: true,
		})
		c.EnsureIndexKey("creator")
		return nil
	})

	var val model.IContactsBook = a
	g.Provide(&inject.Object{Value: val, Name: "IContactsBook"})
}

// GetTotal 查询企业员工总数
func (a *ContactsBook) GetTotal(enterpriseID string) (total int, err error) {
	query := bson.M{
		"deleted":       0,
		"enterprise_id": enterpriseID,
	}
	err = a.DB.C(cUser, func(c *mgo.Collection) error {
		n, err := c.Find(query).Count()
		if err != nil {
			return err
		}
		total = n
		if total == 0 {
			return nil
		}
		return nil
	})
	if err != nil {
		return 0, errors.Wrapf(err, "查询数据发生错误")
	}
	return total, nil
}

// GetAllColleagues 查询所有的同事
func (a *ContactsBook) GetAllColleagues(enterpriseID, colleagues string) ([]*schema.QueryResultColleagues, error) {
	query := bson.M{
		"deleted":       0,
		"enterprise_id": enterpriseID,
	}
	if colleagues != "" {
		query["real_name"] = bson.M{"$regex": fmt.Sprintf("%s", colleagues)}
	}

	var items []*schema.QueryResultColleagues
	err := a.DB.C(cUser, func(c *mgo.Collection) error {
		return c.Find(query).Sort("_id").Skip(0).Limit(200).All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询企业名下的员工信息数据发生错误")
	}

	return items, nil
}

// GetAllFrequentlyUsed 查询所有的常用联系人
func (a *ContactsBook) GetAllFrequentlyUsed(userID string, pageIndex, pageSize uint) ([]*schema.User, error) {
	query := bson.M{
		"deleted": 0,
		"creator": userID,
	}
	var userItem schema.ContactsBook
	var err error
	err = a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		return c.Find(query).One(&userItem)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	var items []*schema.User
	err = a.DB.C(cUser, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": bson.M{"$in": userItem.FrequentlyUsedList}}).Sort("_id").Skip(int(pageIndex - 1)).Limit(int(pageSize)).All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询常用联系人信息数据发生错误")
	}
	return items, nil
}

// AddFrequentlyUsed 添加常用联系人
func (a *ContactsBook) AddFrequentlyUsed(userID string, frequentlyUsedID string) error {
	query := bson.M{
		"deleted": 0,
		"creator": userID,
	}
	var total int
	var err error
	err = a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		total, err = c.Find(query).Count()
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return errors.Wrapf(err, "查询常用联系人是否已经存在：发生错误")
	}
	if total == 0 {
		var referenceItem schema.ContactsBook
		referenceItem.ID = 0
		referenceItem.RecordID = util.UUID()
		referenceItem.Created = time.Now().Unix()
		referenceItem.Deleted = 0
		referenceItem.Creator = userID
		err = a.DB.C(cContactsBook, func(c *mgo.Collection) error {
			id, err := a.DB.IncrID(cContactsBook)
			if err != nil {
				return err
			}
			referenceItem.ID = id
			return c.Insert(&referenceItem)
		})
		if err != nil {
			return errors.Wrapf(err, "创建数据发生错误")
		}
	}
	err = a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		return c.Update(query, bson.M{"$addToSet": bson.M{"frequently_used_list": frequentlyUsedID}})
	})
	if err != nil {
		return errors.Wrapf(err, "更新常用联系人发生错误")
	}

	return nil
}

// CancelFrequentlyUsed 取消常用联系人
func (a *ContactsBook) CancelFrequentlyUsed(userID string, frequentlyUsedID string) error {
	query := bson.M{
		"deleted": 0,
		"creator": userID,
	}
	err := a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		return c.Update(query, bson.M{"$pull": bson.M{"frequently_used_list": frequentlyUsedID}})
	})
	if err != nil {
		return errors.Wrapf(err, "更新常用联系人发生错误")
	}

	return nil
}

// GetColleaguesDetail 查询同事信息详情
func (a *ContactsBook) GetColleaguesDetail(params []string) ([]*schema.UserItemDetail, error) {

	pipeOperator := []bson.M{
		{"$match": bson.M{"record_id": bson.M{"$in": params}, "deleted": 0}},
		{"$lookup": bson.M{"from": "auth_user", "localField": "record_id", "foreignField": "_id", "as": "auth_user"}},
		{"$unwind": bson.M{"path": "$auth_user", "preserveNullAndEmptyArrays": true}},
		{"$match": bson.M{"auth_user.deleted": bson.M{"$eq": 0}}},
		{"$addFields": bson.M{"tel": "$auth_user.tel"}},
		{"$project": bson.M{"user_type": 0, "gender": 0, "created": 0, "operator": 0, "deleted": 0, "auth_user": 0}},
		{"$sort": bson.M{"real_name": 1}},
	}
	var items []*schema.UserItemDetail
	err := a.DB.C(cUser, func(c *mgo.Collection) error {
		return c.Pipe(pipeOperator).All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询分页数据发生错误")
	}
	return items, nil
}

// GetMyFrequentlyUsed 查询指定用户的常用联系人
func (a *ContactsBook) GetMyFrequentlyUsed(userID string) (*schema.ContactsBook, error) {
	query := bson.M{
		"deleted": 0,
		"creator": userID,
	}
	item := new(schema.ContactsBook)
	err := a.DB.C(cContactsBook, func(c *mgo.Collection) error {
		return c.Find(query).One(item)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "更新常用联系人发生错误")
	}

	return item, nil
}
